class WxRequest {
  defaults = {
    baseURL: 'http://192.168.60.28:8024',
    url: '',
    data: null,
    method: 'GET',
    header: {
      'Content-Type': 'application/json'
    },
    timeout: 6000,
    isLoading: true
  }

  queue = []

  interceptors = {
    request: (config) => {
      // 处理请求参数，移除 undefined 和 null 值
      if (config.data) {
        Object.keys(config.data).forEach(key => {
          if (config.data[key] === undefined || config.data[key] === null) {
            delete config.data[key];
          }
        });
      }
      return config;
    },
    response: (response) => {
      // 统一处理响应数据
      if (response.statusCode === 200 && response.data.code === 200) {
        return response.data;
      } else {
        const error = new Error(response.data.message || '请求失败');
        error.response = response;
        throw error;
      }
    }
  }

  constructor(param = {}) {
    this.defaults = Object.assign({}, this.defaults, param);
  }

  request(options) {
    this.timerId && clearTimeout(this.timerId);
    options.url = this.defaults.baseURL + options.url;
    options = { ...this.defaults, ...options }

    if(options.isLoading && options.method !== 'UPLOAD') {
      this.queue.length === 0 && wx.showLoading({
        title: '加载中...',
        mask: true
      })
      this.queue.push('request');
    }

    options = this.interceptors.request(options)
    return new Promise((resolve, reject) => {
      if(options.method === 'UPLOAD') {
        wx.uploadFile({
          ...options,
          success: (res) => {
            try {
              res.data = JSON.parse(res.data);
              const mergeRes = Object.assign({}, res, {config: options, isSuccess: true})
              resolve(this.interceptors.response(mergeRes))
            } catch (error) {
              reject(error);
            }
          },
          fail: (err) => {
            const megeErr = Object.assign({}, err, {config: options, isSuccess: false})
            reject(this.interceptors.response(megeErr))
          }
        })
      } else {
        wx.request({
          ...options,
          success: (res) => {
            try {
              const resParam = Object.assign({}, res, {config: options, isSuccess: true})
              resolve(this.interceptors.response(resParam));
            } catch (error) {
              reject(error);
            }
          },
          fail: (err) => {
            const errParam = Object.assign({}, err, {config: options, isSuccess: false})
            reject(this.interceptors.response(errParam));
          },
          complete: () => {
            if(options.isLoading) {
              this.queue.pop();
              this.queue.length === 0 && this.queue.push('request')
              this.timerId = setTimeout(() => {
                this.queue.pop();
                this.queue.length === 0 && wx.hideLoading();
                clearTimeout(this.timerId);
              }, 1)
            }
          }
        })
      }
    })
  }

  get(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: 'GET' }, config))
  }

  post(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: 'POST' }, config))
  }

  put(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: 'PUT' }, config))
  }

  delete(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: 'DELETE' }, config))
  }

  all(...promise) {
    return Promise.all(promise)
  }

  upload(url, filePath, name = 'file', config = {}) {
    return this.request(
      Object.assign({url, filePath, name, method: 'UPLOAD'}, config)
    )
  }
}

const request = new WxRequest();
export default request;
